package com.yuncheng.oaApi.FlowService;

import cn.hutool.core.bean.BeanUtil;
import com.yuncheng.entity.YcSysUser;
import com.yuncheng.oaApi.constant.OaCommonFlowConstant;
import com.yuncheng.oaApi.constant.OaFlowNodeConstant;
import com.yuncheng.oaApi.constant.OaFlowConstant;
import com.yuncheng.oaApi.constant.OaqxjOaFlowConstants;
import com.yuncheng.oaApi.vo.AgentVo;
import com.yuncheng.oaApi.vo.OaFlowVo;
import com.yuncheng.oaApi.vo.OaReturnVo;
import com.yuncheng.oaApi.vo.Result;
import com.yuncheng.spcyApi.entity.SpcyRsJjrk;
import com.yuncheng.spcyApi.service.ISpcyLogService;
import org.apache.commons.collections.CollectionUtils;
import com.yuncheng.oaApi.utils.GetUuIdUtils;;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.oaApi.busService.OaFlowNodeDbrService;
import com.yuncheng.oaApi.busService.OaFlowNodeService;
import com.yuncheng.oaApi.entity.*;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.oaApi.lcService.OaFlowService;
import com.yuncheng.oaApi.lcService.OalgqsOaFlowService;
import com.yuncheng.oaApi.service.*;
import com.yuncheng.oaApi.service.impl.OaYcSysUserServiceImpl;
import com.yuncheng.spcyApi.utils.DateConvert;
import com.yuncheng.utils.ThreadContextHelper;
import com.yuncheng.vo.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import utils.DateConversionUtils;
import utils.LogUtils;
import utils.ObjectToMapUtils;
import utils.WorkDateUtils;

import java.time.*;
import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component(value = "NewOaqxjFlowService")
public class NewOaqxjOaFlowService extends OaFlowService {
    private static final Logger log = LoggerFactory.getLogger(OalgqsOaFlowService.class);


    @Resource
    private IOaSpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private OaYcSysUserServiceImpl ycSysUserService;

    @Resource
    @Lazy
    private IOaQxjspService oaQxjspService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    @Resource
    @Lazy
    private IOaSpcyRsJjrkService oaSpcyRsJjrkService;

    @Resource
    @Lazy
    private IOaNxjhistoryService oaNxjhistoryService;

    @Resource
    @Lazy
    private IOaSysTzMessageService sysTzMessageService;

    @Resource
    @Lazy
    private IOaSysFlowNodeService sysFlowNodeService;

    @Resource
    @Lazy
    private OaFlowNodeService oaFlowNodeService;

    @Resource
    @Lazy
    private OaFlowNodeDbrService oaFlowNodeDbrService;

    @Resource
    @Lazy
    private IOaSysFlowTempleService sysFlowTempleService;

    @Resource
    @Lazy
    private IOaSysJobService sysJobService;



    //通过名称获取 节点list列表数据，后续可以集成为一个：通过流程模板id和流程名称
    public List<OaSysFlowNode> getNodeList(String nodeName){
        String lcmbCode = OaFlowConstant.OA_QXJ;
        List<OaSysFlowTemple> oaSysFlowTemples = sysFlowTempleService.list(new LambdaQueryWrapper<OaSysFlowTemple>().eq(OaSysFlowTemple::getFlcbm, lcmbCode));
        String templeId = oaSysFlowTemples.get(0).getId();

        if (nodeName.equals(OaFlowConstant.QXJ_HJMC_DWLDSP)) {
            return sysFlowNodeService.list(new LambdaQueryWrapper<OaSysFlowNode>().eq(OaSysFlowNode::getFlcmbid, templeId)
                    .eq(OaSysFlowNode::getFjdmc, OaFlowConstant.QXJ_HJMC_DWLDSP));
        }
        if (nodeName.equals(OaFlowConstant.QXJ_HJMC_FGSP)){
            return sysFlowNodeService.list(new LambdaQueryWrapper<OaSysFlowNode>().eq(OaSysFlowNode::getFlcmbid, templeId)
                    .eq(OaSysFlowNode::getFjdmc,OaFlowConstant.QXJ_HJMC_FGSP));
        }

        if (nodeName.equals(OaFlowConstant.QXJ_HJMC_RSSP)){
            return sysFlowNodeService.list(new LambdaQueryWrapper<OaSysFlowNode>().eq(OaSysFlowNode::getFlcmbid, templeId)
                    .eq(OaSysFlowNode::getFjdmc,OaFlowConstant.QXJ_HJMC_RSSP));
        }

        if (nodeName.equals(OaFlowConstant.QXJ_HJMC_QJQR)){
            return sysFlowNodeService.list(new LambdaQueryWrapper<OaSysFlowNode>().eq(OaSysFlowNode::getFlcmbid, templeId)
                    .eq(OaSysFlowNode::getFjdmc,OaFlowConstant.QXJ_HJMC_QJQR));
        }
        throw new BusinessException("没有找到对应的节点");
    }



    /**
     *
     * @param oaFlowVo
     * @param nowJob
     * @param jobId
     * @param oaid
     * @param submitType
     * @param opinion
     * @return
     */
    public Result handleFlow(OaFlowVo oaFlowVo, OaJobEntity nowJob, String jobId, String oaid, String submitType, String opinion) throws ParseException {

        // 当前流程任务
        if (StringUtils.isNotBlank(jobId)) {
            nowJob = spcySqsxJobService.getById(jobId);
        }

        if (nowJob == null) {
            return Result.error("当前流程任务不存在，请重试");
        }

        if (StringUtils.isBlank(oaid)) {
            oaid = nowJob.getFpid();
        }

        if (StringUtils.isBlank(oaid)) {
            throw new BusinessException("参数丢失，请联系管理员");
        }

        // 提交按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            if (nowJob == null) {
                return Result.error("当前流程任务不存在");
            }
        }
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (currentUser == null) {
            return Result.error("登录已失效，请重新登录");
        }



        // 当前环节办理人名称以及时间
        if (nowJob.getFhjmc().equals(OaFlowConstant.QXJ_HJMC_SQ)){
            //为了防止第一次保存后提交 所以在这个地方在做一次判断 --后续可以将此判读重构为一个方法
            OaQxjsp oaqxjsp =  oaQxjspService.getById(oaid);
            String fts = oaqxjsp.getFts();
            BigDecimal tsDecimal = new BigDecimal(fts);
            String fuserid = oaqxjsp.getFuserid();
            YcSysUser user = ycSysUserService.getById(fuserid);
            String lcmbCode = OaFlowConstant.OA_QXJ;

            if (StringUtils.isBlank(user.getFnxjsyts())){
                throw  new BusinessException("您本年度年假已休完，不能再申请年假，如有疑问请联系人事处！");
            }
            //创建bigdecimal 来比大小
            BigDecimal fnxjsyts = new BigDecimal(user.getFnxjsyts());
            int i1 = fnxjsyts.compareTo(BigDecimal.valueOf(0)); //年休假与0比较
            int i = tsDecimal.compareTo(fnxjsyts); // 请假天数与剩余天数比较

            //在提交流程的时候，如果请休假类型为年休假且为流程在办的时候，则只能有一条数据
            boolean onenxj = onenxj(fuserid);
            if (!onenxj) {
                throw  new BusinessException("有未办结的年休假申请，请先办结未办结的年休假申请，在申请");
            }


            if (oaqxjsp.getFqjlx().equals(OaqxjOaFlowConstants.QXJ_NJ) && i1 == 0) {
                throw  new BusinessException("您本年度年假已休完，不能再申请年假，如有疑问请联系人事处！");
            }
            if (i > 0 && oaqxjsp.getFqjlx().equals(OaqxjOaFlowConstants.QXJ_NJ)) {
                throw  new BusinessException("您的请假天数大于您本年度的年假剩余天数，请修改。如有疑问请联系人事处");
            }

            List<OaSysFlowNode> oaSysFlowNodesDwldsp = getNodeList(OaFlowConstant.QXJ_HJMC_DWLDSP);
            List<OaSysFlowNode> oaSysFlowNodesRssp = getNodeList(OaFlowConstant.QXJ_HJMC_RSSP);
            /**
             * 如果是中心副主任提交 下一环节应该为 单位领导审批
             * 如果是科室负责人 下一环节应该为 人事审批
             */
            if (oaqxjsp.getFbm().contains(OaCommonFlowConstant.ORG_NAME_ZXFZR)) {
              oaFlowVo.setNextNodeId(oaSysFlowNodesDwldsp.get(0).getId());

            } else if (oaFlowNodeDbrService.brksfzr()) {
                oaFlowVo.setNextNodeId(oaSysFlowNodesRssp.get(0).getId());
            } else {
                oaFlowVo.setNextNodeId("");
            }

        }else if (nowJob.getFhjmc().equals(OaFlowConstant.QXJ_HJMC_KSSP)) {
            String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            String name = currentUser.getName();
            OaQxjsp oaqxjsp =  oaQxjspService.getById(oaid);


            oaqxjsp.setFksqm(name);
            oaqxjsp.setFksqmsj(timeStr);
            oaQxjspService.updateById(oaqxjsp);

        } else if (nowJob.getFhjmc().equals(OaFlowConstant.QXJ_HJMC_RSSP)) {
            String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String name = currentUser.getName();
            YcSysUser sysUser = ycSysUserService.getById(currentUser.getId());

//            String fdqnjnd = sysUser.getFdqnjnd();
//            BigDecimal yxts = new BigDecimal(sysUser.getFnxjyxts()); //应休天数
//            BigDecimal syts = new BigDecimal(sysUser.getFnxjsyts()); //剩余天数
//            BigDecimal yxtss = yxts.subtract(syts); //已休天数
//            BigDecimal sytss = syts.subtract(yxtss);
//            String nr = "其"+fdqnjnd+"年年休假"+sysUser.getFnxjyxts()+"，已休"+yxtss+"天，扣除此次休假"+oaqxjsp.getFts()+"天，"
//                        +"/n"+"尚余"+sytss+"天未休。";
//
//
//            oaqxjsp.setFrsyj(nr);

            OaQxjsp oaqxjsp =  oaQxjspService.getById(oaid);


            oaqxjsp.setFrsqm(name);
            oaqxjsp.setFrsqmsj(timeStr);
            oaQxjspService.updateById(oaqxjsp);
            //分管领导审批
        } else if (nowJob.getFhjmc().equals(OaFlowConstant.QXJ_HJMC_FGSP)) {
            String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            String name = currentUser.getName();
            OaQxjsp oaqxjsp =  oaQxjspService.getById(oaid);
            String fts = oaqxjsp.getFts();
            BigDecimal tsDecimal = new BigDecimal(fts);

            oaqxjsp.setFfgqm(name);
            oaqxjsp.setFfgqmsj(timeStr);
            oaQxjspService.updateById(oaqxjsp);
//            int fts = byId.getFts();
            String fuserid = oaqxjsp.getFuserid();
            YcSysUser sysUser = ycSysUserService.getById(fuserid);
            boolean fgldyzxld = oaFlowNodeDbrService.fgldyzxld(sysUser.getOrgName());

            //在分管审批环节，如果请假时间小与等于一天 ，就直接到请假确认，结束流程
            //或者直接结束流程，但是现在没有反馈，所以用第一版，到请假确认然后在提交结束
            int i = tsDecimal.compareTo(BigDecimal.valueOf(1));

            if (i < 0 && submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)) {
                //当前流程id
                oaFlowVo.setNextNodeId(getNodeList(OaFlowConstant.QXJ_HJMC_QJQR).get(0).getId());
            }else if (fgldyzxld){ //如果申请人的分管领导和中心领导是同一人，则也直接提交到请假确认
                oaFlowVo.setNextNodeId(getNodeList(OaFlowConstant.QXJ_HJMC_QJQR).get(0).getId());
            }



        } else if (nowJob.getFhjmc().equals(OaFlowConstant.QXJ_HJMC_DWLDSP)) {
            String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String name = currentUser.getName();
            OaQxjsp oaqxjsp =  oaQxjspService.getById(oaid);


            oaqxjsp.setFzxqm(name);
            oaqxjsp.setFzxqmsj(timeStr);
            oaQxjspService.updateById(oaqxjsp);
        }else if (nowJob.getFhjmc().equals(OaFlowConstant.QXJ_HJMC_QJQR)){

            String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String name = currentUser.getName();
            OaQxjsp oaqxjsp =  oaQxjspService.getById(oaid);


            oaqxjsp.setFqrqjr(name);
            oaqxjsp.setFqrqjsj(timeStr);
            oaQxjspService.updateById(oaqxjsp);
        }


        // 流程环节处理
        Result httpResult = handleNodeName(oaFlowVo, submitType, nowJob, oaid, opinion);
        if (!httpResult.isSuccess()){
            return httpResult;
        }
        //最后一步状态标注流程结束
        /**
         * @Author: lhb
         * @Description :  是最后一步流程 且是 提交 才会判断为流程结束
         * @DateTime:
         * @Params:
         */
        //
        String fnodeid = nowJob.getFnodeid();
        boolean endNode = sysFlowNodeService.endNode(fnodeid);

        if (endNode && submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            //当前流程id
            OaQxjsp oaQxjsp = oaQxjspService.getById(oaid);

            oaQxjsp.setFxjqrr(currentUser.getName());
            oaQxjsp.setFxjqrsj(DateConversionUtils.DateToStringYYYYMMDD(new Date()));

            Calendar calendar = Calendar.getInstance();
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            int minute = calendar.get(Calendar.MINUTE);
            String xjhourStr = hour+":"+minute;

            oaQxjsp.setFxjqrxs(xjhourStr);



            oaQxjsp.setFlczt(OaCommonFlowConstant.FLOW_LCJS);
            //实际请休假时间:先比对 请休假结束时间 和 销假时间
            String fqjjssj = oaQxjsp.getFqjjssj();

            String fqjkssj = oaQxjsp.getFqjkssj();


            long qjkssjtime = DateConversionUtils.StringToDate(fqjkssj).getTime();
            long xjqrsjtime = DateConversionUtils.StringToDate(oaQxjsp.getFxjqrsj()).getTime();

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
            LocalTime nineAm = LocalTime.of(9, 0);

            String fqjksxs = oaQxjsp.getFqjksxs(); //请假开始时间
            //如果请休假结束时间 > 销假时间 那就代表着提前销假
            if (DateConversionUtils.StringToDate(fqjjssj).getTime() > DateConversionUtils.StringToDate(oaQxjsp.getFxjqrsj()).getTime()){
            long ts = 0;
            //如果提前销假只以销假时间和请假开始时间开始算
            long jltshms = qjkssjtime - xjqrsjtime;
            if (jltshms != 0){
                 ts = jltshms / OaCommonFlowConstant.T_YQ / OaCommonFlowConstant.T_MS;
            }
            //如果开始时间和结束时间想等
            if(jltshms == 0){

                if (fqjksxs.equals(OaCommonFlowConstant.QXJSQ_SW)){
                    //如果请假开始小时的时间是上午，那么获取的销假小时的范围
                    //如果销假小时的的范围是 9点之前 那么实际请假时间是0
                    LocalTime givenTime = LocalTime.parse(xjhourStr, formatter);
                    boolean before = givenTime.isBefore(nineAm);
                    if (before){
                        oaQxjsp.setFsjqjsj("0");
                        //如果不是那就向下判断
                    }else {
                        boolean timeBetween = DateConversionUtils.isTimeBetween(xjhourStr, OaCommonFlowConstant.QXJSQ_FWSW, OaCommonFlowConstant.QXJSQ_FWZW);
                        if (timeBetween){
                            oaQxjsp.setFsjqjsj("0.5");
                        }else {
                            boolean timeBetween1 = DateConversionUtils.isTimeBetween(xjhourStr, OaCommonFlowConstant.QXJSQ_FWZW, OaCommonFlowConstant.QXJSQ_FWXW);
                            if (timeBetween1){
                                oaQxjsp.setFsjqjsj("1");
                            }
                        }
                    }
                }
            }
           if(ts == 1){
               if (fqjksxs.equals(OaCommonFlowConstant.QXJSQ_SW)){
                   //如果请假开始小时的时间是上午，那么获取的销假小时的范围
                   //如果销假小时的的范围是 9点之前 那么实际请假时间是0
                   LocalTime givenTime = LocalTime.parse(xjhourStr, formatter);
                   boolean before = givenTime.isBefore(nineAm);
                   if (before){
                       oaQxjsp.setFsjqjsj("1");
                       //如果不是那就向下判断
                   }else {
                       boolean timeBetween = DateConversionUtils.isTimeBetween(xjhourStr, OaCommonFlowConstant.QXJSQ_FWSW, OaCommonFlowConstant.QXJSQ_FWZW);
                       if (timeBetween){
                           oaQxjsp.setFsjqjsj("1.5");
                       }else {
                           boolean timeBetween1 = DateConversionUtils.isTimeBetween(xjhourStr, OaCommonFlowConstant.QXJSQ_FWZW, OaCommonFlowConstant.QXJSQ_FWXW);
                           if (timeBetween1){
                               oaQxjsp.setFsjqjsj("2");
                           }
                       }
                   }
               }
           }
           if (ts > 1){
               if (fqjksxs.equals(OaCommonFlowConstant.QXJSQ_SW)){
                   //如果请假开始小时的时间是上午，那么获取的销假小时的范围
                   //如果销假小时的的范围是 9点之前 那么实际请假时间是0
                   LocalTime givenTime = LocalTime.parse(xjhourStr, formatter);
                   boolean before = givenTime.isBefore(nineAm);
                   if (before){
                       long l = ts + 1 - 1;
                       oaQxjsp.setFsjqjsj(String.valueOf(l));
                       //如果不是那就向下判断
                   }else {
                       boolean timeBetween = DateConversionUtils.isTimeBetween(xjhourStr, OaCommonFlowConstant.QXJSQ_FWSW, OaCommonFlowConstant.QXJSQ_FWZW);
                       if (timeBetween){
                           Double l = ts + 1.5 - 1;
                           oaQxjsp.setFsjqjsj(String.valueOf(l));
                       }else {
                           boolean timeBetween1 = DateConversionUtils.isTimeBetween(xjhourStr, OaCommonFlowConstant.QXJSQ_FWZW, OaCommonFlowConstant.QXJSQ_FWXW);
                           if (timeBetween1){
                               long l = ts + 2 - 1;
                               oaQxjsp.setFsjqjsj(String.valueOf(l));
                           }
                       }
                   }
               }
           }
        }

            oaQxjspService.updateById(oaQxjsp);

            //更新完成后在信息通知表里插入一条消息 表示未读
            sysTzMessageService.endMessage(oaid,false,true,false);

            String fts = oaQxjsp.getFts();
            BigDecimal tsDecimal = new BigDecimal(fts);

            String fqjlx = oaQxjsp.getFqjlx();
            String fsfnnxq = oaQxjsp.getFsfnnxq();
            String fuserid = oaQxjsp.getFuserid(); //请假人id
            YcSysUser user = ycSysUserService.getById(fuserid);

            String fsfnnxq1 = oaQxjsp.getFsfnnxq(); //是否拿年休假请假

            BigDecimal fnxjsyts = new BigDecimal(user.getFnxjsyts());
            BigDecimal fnxjzjts = new BigDecimal(user.getFnxjzjts());
            BigDecimal fzjyxts = new BigDecimal(user.getFzjyxts());


            //先更新连休次数
            Result result = updatelxzt(oaid);
            if (!result.isSuccess()){
                return Result.error(result.getMessage());
            }
            if (StringUtils.isBlank(fqjlx)) {
                throw new BusinessException("无法获取当前流程请假类型，请联系管理员");
            }
            if (StringUtils.isBlank(fuserid)) {
                throw new BusinessException("无法获取当前请假人id,请联系管理员");
            }
            if (fqjlx.equals(OaFlowConstant.QXJ_NJ) || fsfnnxq1 != null) {
                // 转结天数如果大于请假天数 那就直接减 如果小于赋值0
                int i = fnxjsyts.compareTo(BigDecimal.valueOf(0));
                if (i > 0) {
                    BigDecimal newsyts = fnxjsyts.subtract(tsDecimal);
                    user.setFnxjsyts(String.valueOf(newsyts));
                }else if (i < 0) {
                    throw new BusinessException("年休假不满足当前请假");
                }
                int i1 = fzjyxts.compareTo(fnxjzjts);

                BigDecimal newfzjyxtss = i1 < 0 ? fzjyxts.add(BigDecimal.valueOf(1))  : fzjyxts;
                user.setFzjyxts(String.valueOf(newfzjyxtss));

            }
            ycSysUserService.updateById(user);
        }

        return Result.ok("操作成功");
    }

    public Result handleNodeName(OaFlowVo oaFlowVo, String submitType, OaJobEntity job, String oaId, String opinion) {
        HashMap<String, Object> map = oaFlowVo.getMap();
        String dbrid = oaFlowVo.getDbrid();// 下环节待办人
        String smgflag = oaFlowVo.getSmgflag(); // 短信发送标志
        boolean isSubmit = true; // 是否提交流程
        Result res = null;

        // 保存按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SAVE)) {
            updateSqsxJbxx(map, oaId, job);
        }

        // 提交按钮
        if (submitType.equals(OaCommonFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            updateSqsxJbxx(map, oaId, job);

            // 流程任务id
            String jobId = "";
            if (job != null) {
                jobId = job.getId();
            }

            String nextNodeId = "";
            if (StringUtils.isNotBlank(oaFlowVo.getNextNodeId())){
                nextNodeId = oaFlowVo.getNextNodeId();
            }
            // 提交流程任务,待办人是否为空，指定待办人
            if (isSubmit) {
                if (StringUtils.isBlank(dbrid)) {
                    // 提交-流程任务
                    res = this.passJob(oaId, jobId, opinion, nextNodeId, "");
                } else {
                    // 提交-流程任务
                    res = this.passJob(oaId, jobId, opinion, nextNodeId, dbrid);
                }
            }
            if (!res.isSuccess()) {
                return res;
            } else {
                OaJobEntity nowJob = (OaJobEntity) res.getResult();
                // 接收返回的流程任务，如果返回的流程任务id不相等，发送短信
                if (nowJob != null && !jobId.equals(nowJob.getId()) && StringUtils.isNotBlank(smgflag) && smgflag.equals("是")) {

                }
            }
        }

        return Result.ok("提交成功");
    }



    public Result updateSqsxJbxx(HashMap<String, Object> map, String oaid, OaJobEntity job) {
        OaQxjsp oldBasic = oaQxjspService.getById(oaid);
        if (oldBasic == null) {
            return Result.error("当前申请事项【" + oaid + "】不存在，请重试");
        }
        OaQxjsp basicUpdate = null;
        basicUpdate = oldBasic;

        // 修改
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        try {
            BeanUtils.populate(basicUpdate, map);
            oaQxjspService.updateById(basicUpdate);
        } catch (IllegalAccessException e) {
            log.error("出错-保存申请事项【非法访问异常】,{}", e.getMessage());
        } catch (InvocationTargetException e) {
            log.error("出错-保存申请事项【调用TargetException】,{}", e.getMessage());
        }

        String logContent = "基本信息修改: ";
        Map<String, Object> basicMap = ObjectToMapUtils.objectToMap(oldBasic);
        logContent += LogUtils.BeanModifyMsg(basicUpdate, basicMap);

        if (job == null) {
            spcyLogService.addLogs("null", logContent, oaid, OaCommonFlowConstant.LOGS_SYS_TYPE_XG, OaCommonFlowConstant.LOGS_SYS_TYPE_XG);
        } else {
            spcyLogService.addLogs(job.getFhjmc(), logContent, oaid, OaCommonFlowConstant.LOGS_SYS_TYPE_XG, OaCommonFlowConstant.LOGS_SYS_TYPE_XG);
        }

        return Result.ok("保存成功");
    }

    public Map getJobConcernByJobId(String jobid) {
        Map map = new HashMap();

        // 当前流转记录
        OaJobEntity job = spcySqsxJobService.getById(jobid);
        if (job == null) {
            log.error("当前流程任务id为【{}】的流转记录不存在", jobid);
            return map;
        }
        String oaid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(oaid)) {
            log.error("当前流程任务id为【{}】的流转记录中的申请事项id为空", jobid);
            return map;
        }

        // oaid事项基本信息
        OaQxjsp sqsxBasic = oaQxjspService.getById(oaid);

        // 流程任务流传记录
        List<OaJobEntity> jobList = this.getJobListByOaId(oaid);
        String nextNode="";
        String nextNodeId="";

        String fnodeid = job.getFnodeid();

        //判断当前是否是最后一个节点 如果是 返回当前查询
        if (sysFlowNodeService.endNode(fnodeid)){
            List<OaSysFlowNode> nowNode = sysFlowNodeService.getNowNode(fnodeid);
            nextNode = nowNode.get(0).getFjdmc();
            nextNodeId = nowNode.get(0).getId();
        }else {
            List<OaSysFlowNode> nextNode1 = sysFlowNodeService.getNextNode(fnodeid);
            nextNode = nextNode1.get(0).getFjdmc();
            nextNodeId = nextNode1.get(0).getId();
        }
        // 获取下环节待办人
        Map nodeDbrids = oaFlowNodeService.getNodeDbrids(nextNodeId,jobid);

        List<AgentVo> dbrListByMap = oaFlowNodeDbrService.getDbrListByMap(nodeDbrids);


        map.put("sqsx", sqsxBasic); // 申请事项基本信息
        map.put("job", job); // 当前流转记录
        map.put("jobHistoryList", jobList); // 流程任务流传记录
        map.put("nextNodeDbrList", dbrListByMap); // 下环节待办人list
        map.put("nextNode", nextNode);

        return map;
    }

    /**
     * 获取oa-流转记录
     */
    public List<OaJobEntity> getJobListByOaId(String oaid) {
        OaQxjsp byId = oaQxjspService.getById(oaid);
        String flcmbbm = OaFlowConstant.OA_QXJ;
        List<OaSysFlowTemple> list = sysFlowTempleService.list(new LambdaQueryWrapper<OaSysFlowTemple>().eq(OaSysFlowTemple::getFlcbm, flcmbbm));
        String flcmc = list.get(0).getFlcmc();
        LambdaQueryWrapper<OaJobEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(OaJobEntity::getFlcmc, flcmc);
        queryWrapper.eq(OaJobEntity::getFpid, oaid);
        queryWrapper.orderByAsc(OaJobEntity::getCreateTime);
        queryWrapper.orderByAsc(OaJobEntity::getFfssj);
        List<OaJobEntity> jobList = spcySqsxJobService.list(queryWrapper);
        return jobList;
    }

    /**
     *
     * @param lcmbCode 流程模板编码
     * @param oaid 业务id
     * @param currentUser 当前登陆用户
     * @return
     */
    public Result createProcess(String lcmbCode, String oaid, CurrentUserVo currentUser){
        //获取流程模板的第一个环节
        OaSysFlowTemple code = sysFlowNodeService.getCode(lcmbCode);

        List<OaSysFlowNode> node = sysFlowNodeService.getFirstNode(code.getId());

        List<OaJobEntity> list = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>()
                .eq(OaJobEntity::getFpid, oaid)
                .eq(OaJobEntity::getFhjmc, node.get(0).getFjdmc())
                .eq(OaJobEntity::getFlcmc,code.getFlcmc())
        );
        if(list.size()>0){
            List<String> ids = list.stream().map(OaJobEntity::getId).collect(Collectors.toList());
            spcySqsxJobService.removeBatchByIds(ids);
        }
        return this.createJob(lcmbCode,oaid,"",node.get(0),null,null,currentUser);
    }


    /**
     *  提交环节待办记录 并创建下一环节待办
     *
     * @param oaId 业务id
     * @param jobId 流程id
     * @param opinion 意见
     * @param nextNodeId 下一节点id
     * @param nextNodeDbrIds 下一节点待办人
     * @return
     */
    public Result passJob(String oaId, String jobId, String opinion,String nextNodeId,String nextNodeDbrIds){
        //处理业务表的逻辑
        String lcmbCode = "";

        lcmbCode = OaFlowConstant.OA_QXJ;
        Result httpResult = passJob(lcmbCode, oaId, jobId, opinion, nextNodeId, nextNodeDbrIds,true);
        return httpResult;
    }

    /**
     *
     * @param nowNodeid 当前节点id
     * @param jobId 当前流程id
     * @return
     * 获取环节待办人
     */
    public Map getNodeDbrids(String nowNodeid,String jobId){
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        OaSysFlowNode oaSysFlowNode = sysFlowNodeService.getById(nowNodeid);
        Integer fsfcjdpzhq = oaSysFlowNode.getFsfcjdpzhq(); //是否从节点配置获取待办人
        String fblbmlx = oaSysFlowNode.getFblbmlx(); //办理部门类型
        String fblbmid = oaSysFlowNode.getFblbmid(); //办理部门id

        String fblgwid = oaSysFlowNode.getFblgwid(); //办理岗位id

        String fblrid = oaSysFlowNode.getFblrid(); //办理人id
        Integer fsfzdblr = oaSysFlowNode.getFsfzdblr(); //是否指定办理人
        Integer fsfzddlr= oaSysFlowNode.getFsfzddlr(); //是否指定登陆人为办理人
        Map map = new HashMap();
        //是否从节点配置获取待办人：0是 / 1否  为0则读取当前节点配置的环节办理人
        if (fsfcjdpzhq.equals(OaFlowNodeConstant.SFZD_YES)){
            //如果指定办理人 直接返回指定人
            if (fsfzdblr.equals(OaFlowNodeConstant.SFZD_YES)){
                if (StringUtils.isBlank(fblrid)){
                    throw new BusinessException("查询不到指定办理人");
                }
                String dbrName = oaFlowNodeDbrService.getDbrNameById(fblrid);
                map.put("dbr",dbrName);
                map.put("dbrId",fblrid);
                return map;
            }
            //如果指定当前登陆人 则返回当前登录用户
            if (fsfzddlr.equals(OaFlowNodeConstant.SFZD_YES)){
                String dbrid = currentUser.getId();
                String dbrname = currentUser.getName();
                map.put("dbr",dbrname);
                map.put("dbrId",dbrid);
                return map;
            }
            Map dbrByBmGw = getDbrByBmGw(fblbmid, fblgwid);
            //如果办理部门类型为 指定 则待办人 进入 根据部门和岗位判断
            if (fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_ZD)){
                return dbrByBmGw;
                //在判断 办理部门类型为 不指定 则 待办人 根据 办理岗位id 来 判断
            }else if(fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_BZD)){
                //否则根据办理部门id返回待办人
                return dbrByBmGw;
            }else if (fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_DQBM) && StringUtils.isNotBlank(jobId)){
                //在这里写 如果 为当前部门 传入 业务id 根据 jobid 拿到所有信息
                //通过jobId 拿到nowNodeId
                OaJobEntity oaJobEntity = spcySqsxJobService.getById(jobId);
                String fnodeid = oaJobEntity.getFnodeid(); //获取当前节点id
                String fpid = oaJobEntity.getFpid();
                OaSysFlowNode flowNodeServiceById = sysFlowNodeService.getById(fnodeid);
                String flcmbid = flowNodeServiceById.getFlcmbid(); //通过流程模板id 可以获取流程节点的第一个环节
                List<OaSysFlowNode> firstNode = sysFlowNodeService.getFirstNode(flcmbid);
                String firstNodeId = firstNode.get(0).getId();//获取第一个流程节点的id
                //通过流程节点id 和jobid 对比 获取第一环节办理人姓名和id
                List<OaJobEntity> list = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>().eq(OaJobEntity::getFpid, fpid)
                        .eq(OaJobEntity::getFnodeid, firstNodeId));
                String fdbrid = list.get(0).getFdbrid();
                //String orgId = ycSysUserService.getById(fdbrid).getOrgId();
                String orgId = ycSysUserService.getUserZbmByUserId(fdbrid);
                Map ByBmGw = getDbrByBmGw(orgId, fblgwid);
                return ByBmGw;
            }else if (fblbmlx.equals(OaFlowNodeConstant.BLJD_BLBM_DQBM)){
                return dbrByBmGw;
            }
        }else {
            map.put("dbr", "");
            map.put("dbrId", "");
            return map;
        }
        return map;
    }

    //根据办理部门id 和 办理岗位id 判断返回待办人
    public Map  getDbrByBmGw(String fblbmid,String fblgwid){
        Map map = new HashMap();
        String dbr="";
        String dbrid="";
        //null null  办理部门id和办理岗位id都为空 直接返回为空
        if (StringUtils.isBlank(fblbmid) && StringUtils.isBlank(fblgwid)){
            map.put("dbr",dbr);
            map.put("dbrId",dbrid);
            return map;
        }
        //null not  办理部门id为空 办理岗位id不为空  返回当前办理岗位的所有人
        if (StringUtils.isBlank(fblbmid) && StringUtils.isNotBlank(fblgwid)){
            //
            return oaFlowNodeDbrService.getDbrByGwid(fblgwid);
        }
        //not null 办理部门id不为空 办理岗位id为空  返回当前部门id的所有人
        if (StringUtils.isNotBlank(fblbmid) && StringUtils.isBlank(fblgwid)){
            return oaFlowNodeDbrService.getDbrByBmid(fblbmid);
        }
        // not not 办理部门id 和办理岗位id 都不为空 则返回当前部门下 当前办理岗位的用户
        if (StringUtils.isNotBlank(fblbmid) && StringUtils.isNotBlank(fblgwid)){
            //先判断办理岗位id 是不是分管领导
            List<OaSysJob> oaSysJobs = sysJobService.list(new LambdaQueryWrapper<OaSysJob>().eq(OaSysJob::getId, fblgwid));
            String jobName = oaSysJobs.get(0).getJobName();
            if (jobName.equals(OaFlowNodeConstant.ROLE_NAME_FGLD)){
                return oaFlowNodeDbrService.getKsFgldByDeptName(fblbmid);
            }else {
                return oaFlowNodeDbrService.getdbrByDeptName(fblbmid, fblgwid);
            }


        }
        map.put("dbr",dbr);
        map.put("dbrId",dbrid);
        return map;
    }


    /**
     * 创建流程
     * @param lcmbCode 流程编码code
     * @param pid 业务id
     * @param dbrId 待办人id
     * @param nowNode 当前节点对象
     * @param nowJob 当前流程对象
     * @param nextNodeId 下一环节id
     * @param currentUser 当前登陆人
     * @return
     */
    public Result createJob(String lcmbCode, String pid, String dbrId, OaSysFlowNode nowNode, OaJobEntity nowJob, String nextNodeId, CurrentUserVo currentUser){
        String jobId = "";
        //如果  nextNodeId 不为空 则nowNode 直接等于传过来的nextNodeId 否则在判断 nowJob 为不为空
        if (StringUtils.isNotBlank(nextNodeId)){
            nowNode = sysFlowNodeService.getById(nextNodeId);
            if (nowJob != null){
                jobId = nowJob.getId();
            }
        } else
            //如果nowJob 不为空
            if (nowJob != null) {
                String fnodeid1 = nowJob.getFnodeid();
                jobId = nowJob.getId();
                List<OaSysFlowNode> nextNode = sysFlowNodeService.getNextNode(fnodeid1);
                if (nextNode == null) {
                    throw new BusinessException("下环节为空");
                }
                if (nextNode.size() > 1) {
                    if (StringUtils.isBlank(nextNodeId)) {
                        throw new BusinessException("请选择提交环节");
                    } else {
                        nowNode = sysFlowNodeService.getById(nextNodeId);
                    }
                } else {
                    nowNode = nextNode.get(0);
                }
            }else {
                if (nowNode == null) {
                    throw new BusinessException("指定下环节");
                }

            }
        String fnodeid = "";
        fnodeid = nowNode.getId();

        String fblfs = nowNode.getFblfs();
        String fjdmc = nowNode.getFjdmc();
        Integer fsfcjdpzhq = nowNode.getFsfcjdpzhq();

        String lcmc = sysFlowNodeService.getCode(lcmbCode).getFlcmc();

        OaJobEntity job = new OaJobEntity();
        job.setId(GetUuIdUtils.generateUuid());
        job.setFpid(pid);
        job.setFblfs(fblfs);
        job.setFhjmc(fjdmc);
        job.setFywlx(OaFlowConstant.OA);
        job.setFblzt(OaCommonFlowConstant.BLZT_DB);
        if(nowJob == null){
            job.setFsyhjid("");
        }else {
            job.setFsyhjid(nowJob.getId());
        }

        job.setFlcmc(lcmc);
        job.setFnodeid(fnodeid);
        if(currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }
        job.setFfssj(new Date());
        //待办人和原待办人
        if (StringUtils.isNotBlank(dbrId)){
            job.setFdbrid(dbrId);
            job.setFdbr(oaFlowNodeDbrService.getDbrNameById(dbrId));
            job.setFydbr(oaFlowNodeDbrService.getDbrNameById(dbrId));
            job.setFydbrid(dbrId);
            spcySqsxJobService.save(job);
            return Result.ok(job);
        }


        if (fsfcjdpzhq.equals(OaFlowNodeConstant.SFZD_YES)){
            Map nodeDbrids = getNodeDbrids(fnodeid,jobId);
            dbrId = nodeDbrids.get("dbrId").toString();
            String dbr = nodeDbrids.get("dbr").toString();
            job.setFdbr(dbr);
            job.setFdbrid(dbrId);
            job.setFydbr(dbr);
            job.setFydbrid(dbrId);
            spcySqsxJobService.save(job);
            return Result.ok(job);
        }else{
            String dbrName = oaFlowNodeDbrService.getDbrNameById(dbrId);
            job.setFdbr(dbrName);
            job.setFdbrid(dbrId);
            job.setFydbr(dbrName);
            job.setFydbrid(dbrId);
            spcySqsxJobService.save(job);
            return Result.ok(job);
        }
    }


    /**
     *  提交任务
     * @param lcmbCode 流程模板编码
     * @param pid 主业务id
     * @param jobId 流程id
     * @param opinion 意见
     * @param nextNodeId 下一节点id
     * @param nextNodeDbrIds 下一节点待办人
     * @param isOverCurrentJob 是否办结 创建
     * @return
     */
    public Result passJob(String lcmbCode,String pid, String jobId, String opinion,String nextNodeId,String nextNodeDbrIds,boolean isOverCurrentJob){

        // 获得当前待办任务，并做校验
        OaJobEntity job= spcySqsxJobService.getById(jobId);
        if (job==null){
            return Result.error("查不到id为【"+jobId+"】的待办任务");
        }

        //获取办理人，并做办理人的校验，如果当前登录人不是待办人之一，拒绝办理
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (currentUser == null){
            return Result.error("请先登录");
        }
        if(isOverCurrentJob){
            //办理掉当前环节
            Result result = doJob(jobId,opinion);
            //在这里判断 是否是最后一个节点 如果是返回一个新的空对象
            boolean endNode = sysFlowNodeService.endNode(job.getFnodeid());
            if (endNode){
                OaJobEntity job1 = new OaJobEntity();
                return  Result.ok(job1);
            }

            job = (OaJobEntity) result.getResult();
            //生成下一环节的待办
            if(result.isSuccess()){
//                job = (SpcySqsxJob) result.getResult();

                if(job.getFblzt().equals(OaCommonFlowConstant.BLZT_YB)){
                    //创建下一环节任务
                    Result result1= createJob(lcmbCode,pid,nextNodeDbrIds,null,job,nextNodeId,currentUser);
                    if (!result1.isSuccess()){
                        return Result.error(result1.getMessage());
                    }else {
                        // 3-16 返回新增的流程任务
                        return Result.ok(result1.getResult());
                    }
                }
                // 3-16 返回当前流程任务
                return Result.ok(job);
            }else{
                return Result.error(result.getMessage());
            }
        }else{

            //创建下一环节任务
            Result result1= createJob(lcmbCode,pid,nextNodeDbrIds,null,job,nextNodeId,currentUser);
            if (!result1.isSuccess()){
                return Result.error(result1.getMessage());
            }else {
                // 3-16 返回新增的流程任务
                return Result.ok(result1.getResult());
            }
        }
    }

    /**
     * 办理环节
     *
     * @param job         当前流程任务
     * @param currentUser 当前用户
     * @param opinion     意见
     * @param returnNode  退回环节
     */
    private Result doJob(OaJobEntity job, CurrentUserVo currentUser, String opinion, String returnNode) {
        String blrId = "";
        String blr = "";
        String blbm = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
            blbm = currentUser.getOrgName();
        }
        if (job == null) {
            return Result.error("当前流程任务不存在，请重试");
        }
//        if(CommonFlowConstant.BLZT_YB.equals(job.getFblzt())){
//            return Result.error("当前任务已提交");
//        }
        if (StringUtils.isBlank(job.getFdbrid())) {
            return Result.error("当前任务未指定办理人");
        }
//        if(!job.getFdbrid().contains(blrId)){
//            return Result.error("当前登录用户无此任务的办理权限");
//        }
        // 办理方式 竞争办理 、多人线性办理 、多人并行办理
        String blfs = job.getFblfs();
        if (StringUtils.isBlank(blfs) || blfs.equals(OaCommonFlowConstant.BLFS_DRJJ)) {
            job.setFblr(blr);
            job.setFblsj(new Date());
            job.setFblyj(opinion);
            job.setFblzt(OaCommonFlowConstant.BLZT_YB);
            if (StringUtils.isBlank(returnNode)) {
                job.setFbllx(OaCommonFlowConstant.BLLX_BL);
            } else {
                job.setFbllx(returnNode);
            }
            job.setFblbm(blbm);

            // 审评查验流程 计算 办理天数、是否超时
            /*if (StringUtils.isNotBlank(job.getFlcmc()) && job.getFlcmc().contains(YpscFlowConstant.LCMC_LIKE_SPCYLC)) {
                job.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(job.getFksyts(),job.getFpid(),job.getFfssj(), job.getFblsj(), job.getFztkssj(),job.getFztjssj())); // 使用天数
                job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时
            }*/

            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        } else if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX) || blfs.equals(OaCommonFlowConstant.BLFS_DRBX)) {
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId = "";
            String nextBlr = "";
            if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX)) {
                String ydbrIds[] = job.getFydbrid().split(",");
                String ydbrs[] = job.getFydbr().split(",");
                for (int i = 0; i < ydbrIds.length; i++) {
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (dbrId.equals(blrId)) {
                        if (i + 1 < ydbrIds.length) {
                            nextBlrId = ydbrIds[i + 1];
                            nextBlr = ydbrs[i + 1];
                            break;
                        }
                    }
                }
            } else {
                String dbrIds[] = job.getFdbrid().split(",");
                String dbrs[] = job.getFdbr().split(",");
                for (int i = 0; i < dbrIds.length; i++) {
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (!dbrId.equals(blrId)) {
                        nextBlrId = nextBlrId + (StringUtils.isBlank(nextBlrId) ? "" : ",") + dbrId;
                        nextBlr = nextBlr + (StringUtils.isBlank(nextBlr) ? "" : ",") + dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            job.setFblr(blr);
            job.setFblsj(new Date());
            String blyj = (job.getFblyj() == null ? "" : job.getFblyj()) + (StringUtils.isBlank(job.getFblyj()) ? "" : "@@") + DateConversionUtils.DateToString(new Date()) + "|" + blr + "|" + opinion;
            job.setFblyj(blyj);
            if (StringUtils.isBlank(nextBlrId)) {
                job.setFblzt(OaCommonFlowConstant.BLZT_YB);
                if (StringUtils.isBlank(returnNode)) {
                    job.setFbllx(OaCommonFlowConstant.BLLX_BL);
                } else {
                    job.setFbllx(returnNode);
                }
                job.setFblbm(blbm);
            } else {
                job.setFblzt(OaCommonFlowConstant.BLZT_DB);
                job.setFdbrid(nextBlrId);
                job.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /**
     * @param job
     * @Description 办结当前环节
     */
    public Result doJob(String job, String opinion) {
        OaJobEntity byId = spcySqsxJobService.getById(job);
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        String blrId = "";
        String blr = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
        }
        if (job == null) {
            return Result.error("当前流程任务不存在，请重试");
        }
        if (OaCommonFlowConstant.BLZT_YB.equals(byId.getFblzt())) {
            return Result.error("当前任务已提交");
        }
//        if(StringUtils.isBlank(job.getFdbrid())){
//            return Result.error("当前任务未指定办理人");
//        }
        if (!byId.getFdbrid().contains(blrId)) {
            return Result.error("当前登录用户无此任务的办理权限");
        }
        // 办理方式  、多人竞争办理
        String blfs = byId.getFblfs();
        if (StringUtils.isBlank(blfs) || blfs.equals(OaCommonFlowConstant.BLFS_DRJJ)) {
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            byId.setFblyj(opinion);
            byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            spcySqsxJobService.updateById(byId);
            return Result.ok(byId);
        } else if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX) || blfs.equals(OaCommonFlowConstant.BLFS_DRBX)) {
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId = "";
            String nextBlr = "";
            if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX)) {
                String ydbrIds[] = byId.getFydbrid().split(",");
                String ydbrs[] = byId.getFydbr().split(",");
                for (int i = 0; i < ydbrIds.length; i++) {
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (dbrId.equals(blrId)) {
                        if (i + 1 < ydbrIds.length) {
                            nextBlrId = ydbrIds[i + 1];
                            nextBlr = ydbrs[i + 1];
                            break;
                        }
                    }
                }
            } else {
                String dbrIds[] = byId.getFdbrid().split(",");
                String dbrs[] = byId.getFdbr().split(",");
                for (int i = 0; i < dbrIds.length; i++) {
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (!dbrId.equals(blrId)) {
                        nextBlrId = nextBlrId + (StringUtils.isBlank(nextBlrId) ? "" : ",") + dbrId;
                        nextBlr = nextBlr + (StringUtils.isBlank(nextBlr) ? "" : ",") + dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            String blyj = (byId.getFblyj() == null ? "" : byId.getFblyj()) + (StringUtils.isBlank(byId.getFblyj()) ? "" : "@@") + DateConversionUtils.DateToString(new Date()) + "|" + blr + "|" + opinion;
            byId.setFblyj(blyj);
            if (StringUtils.isBlank(nextBlrId)) {
                byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            } else {
                byId.setFblzt(OaCommonFlowConstant.BLZT_DB);
                byId.setFdbrid(nextBlrId);
                byId.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(byId);
            return Result.ok(byId);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /***
     * 批量销假 使用 办结
     */
    public Result doJobs(String job, String opinion) {
        OaJobEntity byId = spcySqsxJobService.getById(job);
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        String blrId = "";
        String blr = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
        }
        if (job == null) {
            return Result.error("当前流程任务不存在，请重试");
        }
        if (OaCommonFlowConstant.BLZT_YB.equals(byId.getFblzt())) {
            return Result.error("当前任务已提交");
        }
//        if(StringUtils.isBlank(job.getFdbrid())){
//            return Result.error("当前任务未指定办理人");
//        }
//        if (!byId.getFdbrid().contains(blrId)) {
//            return Result.error("当前登录用户无此任务的办理权限");
//        }
        // 办理方式  、多人竞争办理
        String blfs = byId.getFblfs();
        if (StringUtils.isBlank(blfs) || blfs.equals(OaCommonFlowConstant.BLFS_DRJJ)) {
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            byId.setFblyj(opinion);
            byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            spcySqsxJobService.updateById(byId);
            return Result.ok(job);
        } else if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX) || blfs.equals(OaCommonFlowConstant.BLFS_DRBX)) {
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId = "";
            String nextBlr = "";
            if (blfs.equals(OaCommonFlowConstant.BLFS_DRXX)) {
                String ydbrIds[] = byId.getFydbrid().split(",");
                String ydbrs[] = byId.getFydbr().split(",");
                for (int i = 0; i < ydbrIds.length; i++) {
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (dbrId.equals(blrId)) {
                        if (i + 1 < ydbrIds.length) {
                            nextBlrId = ydbrIds[i + 1];
                            nextBlr = ydbrs[i + 1];
                            break;
                        }
                    }
                }
            } else {
                String dbrIds[] = byId.getFdbrid().split(",");
                String dbrs[] = byId.getFdbr().split(",");
                for (int i = 0; i < dbrIds.length; i++) {
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (!dbrId.equals(blrId)) {
                        nextBlrId = nextBlrId + (StringUtils.isBlank(nextBlrId) ? "" : ",") + dbrId;
                        nextBlr = nextBlr + (StringUtils.isBlank(nextBlr) ? "" : ",") + dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            byId.setFblr(blr);
            byId.setFblsj(new Date());
            String blyj = (byId.getFblyj() == null ? "" : byId.getFblyj()) + (StringUtils.isBlank(byId.getFblyj()) ? "" : "@@") + DateConversionUtils.DateToString(new Date()) + "|" + blr + "|" + opinion;
            byId.setFblyj(blyj);
            if (StringUtils.isBlank(nextBlrId)) {
                byId.setFblzt(OaCommonFlowConstant.BLZT_YB);
            } else {
                byId.setFblzt(OaCommonFlowConstant.BLZT_DB);
                byId.setFdbrid(nextBlrId);
                byId.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(byId);
            return Result.ok(byId);
        }
        return Result.error("待办任务未指定办理方式");
    }


    /**
     * 查询流程当前环节-上一环节
     * * @param jobid 流程任务id
     * * @param isZdhj 是否指定环节
     * * @return
     */
    public List<Map<String, String>> getCurrentJobPrevious(String jobid, boolean isZdhj) {
        if (StringUtils.isBlank(jobid)) {
            throw new BusinessException("流程任务参数为空！");
        }

        OaJobEntity currentJob = spcySqsxJobService.getById(jobid);
        if (currentJob == null) {
            throw new BusinessException("当前流程任务不存在！");
        }


        String fpid = currentJob.getFpid(); // 关联业务id
        String flcmc = currentJob.getFlcmc(); // 所属流程名称
        String fnodeid = currentJob.getFnodeid(); //当前节点名称


        List<Map<String, String>> ybNodeList = new ArrayList<>(); // 退回环节数组
        String previousNode = this.getPreviousNodeBynodeId(fnodeid); // 上一环节

        // 指定环节
        if (isZdhj) {
            List<OaJobEntity> preJobList = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>()
                    .eq(OaJobEntity::getFpid, fpid)
                    .eq(OaJobEntity::getFblzt, OaCommonFlowConstant.BLZT_YB)
                    .eq(OaJobEntity::getFlcmc, flcmc)
                    .orderByAsc(OaJobEntity::getFfssj));
            if (CollectionUtils.isNotEmpty(preJobList)) {
                for (OaJobEntity job : preJobList) {

                    // 判断是否存在一样的环节名称，存在跳出当次循环
                    boolean isExistNode = false;
                    if (CollectionUtils.isNotEmpty(ybNodeList)) {
                        for (Map<String, String> disMap : ybNodeList) {
                            if (disMap.get("fhjmc").equals(job.getFhjmc())) {
                                isExistNode = true;
                                break;
                            }
                        }
                    }
                    if (isExistNode) {
                        continue;
                    }
                    Map<String, String> map = new HashMap<>();
                    map.put("id", job.getId());
                    map.put("fhjmc", job.getFhjmc());
                    ybNodeList.add(map);
                }
            }
        } else {
            // 查询上一环节是否存在
            List<OaJobEntity> preJobList = spcySqsxJobService.list(new LambdaQueryWrapper<OaJobEntity>()
                    .eq(OaJobEntity::getFpid, fpid)
                    .eq(OaJobEntity::getFhjmc, previousNode)
                    .eq(OaJobEntity::getFblzt, OaCommonFlowConstant.BLZT_YB)
                    .eq(OaJobEntity::getFlcmc, flcmc)
                    .orderByDesc(OaJobEntity::getFfssj));

            if (CollectionUtils.isNotEmpty(preJobList)) {
                Map<String, String> map = new HashMap<>();
                map.put("id", preJobList.get(0).getId());
                map.put("fhjmc", preJobList.get(0).getFhjmc());
                ybNodeList.add(map);
            }
        }
        return ybNodeList;
    }

    /**
     * 退回流程 - 指定环节
     */
    public void returnZdJob(OaReturnVo oaReturnVo) {
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (currentUser == null) {
            throw new BusinessException("登录已失效，请重新登录！");
        }

        if (StringUtils.isBlank(oaReturnVo.getJobid())) {
            throw new BusinessException("流程任务参数为空！");
        }

        if (StringUtils.isBlank(oaReturnVo.getOpinion())) {
            throw new BusinessException("请填写退回意见！");
        }

        if (StringUtils.isBlank(oaReturnVo.getShjid())) {
            throw new BusinessException("请选择退回环节！");
        }

        // 当前环节
        OaJobEntity currentJob = spcySqsxJobService.getById(oaReturnVo.getJobid());
        if (currentJob == null) {
            throw new BusinessException("当前流程任务不存在！");
        }

        String sqsxid = currentJob.getFpid();
        String oldfhjmc = currentJob.getFhjmc();


        // 上一环节
        OaJobEntity previousJob = spcySqsxJobService.getById(oaReturnVo.getShjid());
        if (currentJob == null) {
            throw new BusinessException("当前流程任务不存在！");
        }
        String previousNode = previousJob.getFhjmc();

        String bllx = "[" + oldfhjmc + "]" + OaCommonFlowConstant.BLLX_TH + "[" + previousNode + "]";
        Result result = this.doJob(currentJob, currentUser, oaReturnVo.getOpinion(), bllx);
        if (!result.isSuccess()) {
            throw new BusinessException(result.getMessage());
        }

        /**
         * 创建退回环节流程任务
         */
        OaJobEntity newPreviousJob = new OaJobEntity();
        BeanUtil.copyProperties(previousJob, newPreviousJob);
        newPreviousJob.setId(GetUuIdUtils.NotReplaceUuId());

        if (StringUtils.isBlank(newPreviousJob.getFpid())) {
            newPreviousJob.setFpid(sqsxid);
        }


        newPreviousJob.setFblzt(OaCommonFlowConstant.BLZT_TH);
        newPreviousJob.setFthyj(oaReturnVo.getOpinion());
        newPreviousJob.setFlcmc(OaFlowConstant.OA_QXJ_NAME);
        newPreviousJob.setFblyj("");
        newPreviousJob.setFblr("");
        newPreviousJob.setFblsj(null);
        newPreviousJob.setFblbm("");
        newPreviousJob.setFbllx(bllx);
        newPreviousJob.setFfssj(new Date());
        newPreviousJob.setFfsrid(currentUser.getId());
        newPreviousJob.setFfsrmc(currentUser.getName());
        newPreviousJob.setFsfkch("");
        spcySqsxJobService.save(newPreviousJob);
        //处理主表数据
        OaQxjsp oaQxjsp = oaQxjspService.getById(sqsxid);
        if (previousNode.equals(OaFlowConstant.QXJ_HJMC_SQ)) {
            oaQxjsp.setFksqm("");
            oaQxjsp.setFksqmsj("");
            oaQxjsp.setFksyj("");
            oaQxjsp.setFrsqmsj("");
            oaQxjsp.setFrsqm("");
            oaQxjsp.setFrsyj("");
            oaQxjsp.setFfgqmsj("");
            oaQxjsp.setFfgqm("");
            oaQxjsp.setFfgyj("");
            oaQxjsp.setFzxqmsj("");
            oaQxjsp.setFzxqm("");
            oaQxjsp.setFzxyj("");
            oaQxjsp.setFlczt(OaCommonFlowConstant.FLOW_LCZB);
        } else if (previousNode.equals(OaFlowConstant.QXJ_HJMC_KSSP)) {
            oaQxjsp.setFrsqmsj("");
            oaQxjsp.setFrsqm("");
            oaQxjsp.setFrsyj("");
            oaQxjsp.setFfgqmsj("");
            oaQxjsp.setFfgqm("");
            oaQxjsp.setFfgyj("");
            oaQxjsp.setFzxqmsj("");
            oaQxjsp.setFzxqm("");
            oaQxjsp.setFzxyj("");
            oaQxjsp.setFlczt(OaCommonFlowConstant.FLOW_LCZB);
        } else if (previousNode.equals(OaFlowConstant.QXJ_HJMC_RSSP)) {
            oaQxjsp.setFfgqmsj("");
            oaQxjsp.setFfgqm("");
            oaQxjsp.setFfgyj("");
            oaQxjsp.setFzxqmsj("");
            oaQxjsp.setFzxqm("");
            oaQxjsp.setFzxyj("");
            oaQxjsp.setFlczt(OaCommonFlowConstant.FLOW_LCZB);
        } else if (previousNode.equals(OaFlowConstant.QXJ_HJMC_FGSP)) {
            oaQxjsp.setFzxqmsj("");
            oaQxjsp.setFzxqm("");
            oaQxjsp.setFzxyj("");
            oaQxjsp.setFlczt(OaCommonFlowConstant.FLOW_LCZB);
        } else {
            oaQxjsp.setFlczt(OaCommonFlowConstant.FLOW_LCZB);
        }
        oaQxjspService.updateById(oaQxjsp);
    }


    /**
     * 获取上一环节-通过当前流程节点id
     *
     * @param nodeId 当前节点id
     * @return
     */
    private String getPreviousNodeBynodeId(String nodeId) {
        String preNode = "";
        List<OaSysFlowNode> previousNode = sysFlowNodeService.getPreviousNode(nodeId);
        preNode=  previousNode.get(0).getFjdmc();
        return preNode;
    }



    /**
     * @param:
     * @Description: 判断请假天数后是否有调休日
     * @auther: lhb
     * @date: 2023/9/14 10:46
     */
    //提交的情况下如果年休假在节假日前后，则将用户表字段 本年度是否与节假日连休为 赋值为是 、每年在年休假效期结束时间 后一个月更新/或在年休假效期结束时间后一天更新
    //判断请假时间的结束日期后一天是否是调休
    public boolean sflx(String oaid, int ts) throws ParseException {
        OaQxjsp byId = oaQxjspService.getById(oaid);
        String fqjkssj = byId.getFqjkssj();
        //转化为data类型
        String format = "yyyy-MM-dd";
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        if (StringUtils.isBlank(fqjkssj)){
            throw new BusinessException("获取不到请假开始日期，请联系管理员");
        }
        Date qjkssj = dateFormat.parse(fqjkssj);
        long qjkssjTime = qjkssj.getTime();
        //开始时间不可能在调休的时候请假，所以现在默认是在调休的前一天请假，然后和调休一起，之后在与办公室对接，如果与调休连休需要知道提前几天请假
        List<Date> txDateList = new ArrayList<>();
        List<SpcyRsJjrk> txList = oaSpcyRsJjrkService.list(new LambdaQueryWrapper<SpcyRsJjrk>()
                .like(SpcyRsJjrk::getFjjrlx, OaCommonFlowConstant.JJRK_LX_TX)
                .orderByAsc(SpcyRsJjrk::getFjjrsj));
        if (CollectionUtils.isNotEmpty(txList)) {
            txDateList = txList.stream().map(SpcyRsJjrk::getFjjrsj).collect(Collectors.toList());
        }
        //拿到请假几天，然后循环几次，看循环到的最后的日期是不是调休
        for (int i = 0; i <= ts; i++) {
            qjkssjTime += 86400000;
        }
        Date startDate = new Date(qjkssjTime); // 使用毫秒数创建Date对象
        boolean tx = WorkDateUtils.isExists(startDate, txDateList); //判斷是否在调休内
        return tx;
    }



    //更新是与节假日连休的次数
    public Result updatelxzt(String oaid) throws ParseException {
        //拿到当前数据，如果结束日期的后一天是假期 那么 就+1 然后更新用户数据
        OaQxjsp oaQxjsp = oaQxjspService.getById(oaid);
        String fqjjssj = oaQxjsp.getFqjjssj(); //请休假结束时间
        String fuserid = oaQxjsp.getFuserid();
        YcSysUser user = ycSysUserService.getById(fuserid); //具体人
        Integer fsfyjjrlx = user.getFsfyjjrlx();
        if(fsfyjjrlx == null){
            fsfyjjrlx = 0;
        }

        String format = "yyyy-MM-dd";
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        if (StringUtils.isBlank(fqjjssj)){
            throw new BusinessException("获取不到请假结束日期，请联系管理员");
        }
        Date qjkssj = dateFormat.parse(fqjjssj);
        long fqjjsrqTime = qjkssj.getTime(); //请假结束时间
        fqjjsrqTime = fqjjsrqTime + 86400000; //加一天
        Date startDate = new Date(fqjjsrqTime); // 使用毫秒数创建Date对象
        //查询调休
        List<Date> txDateList = new ArrayList<>();
        List<SpcyRsJjrk> txList = oaSpcyRsJjrkService.list(new LambdaQueryWrapper<SpcyRsJjrk>()
                .like(SpcyRsJjrk::getFjjrlx, OaCommonFlowConstant.JJRK_LX_TX)
                .orderByAsc(SpcyRsJjrk::getFjjrsj));
        if (CollectionUtils.isNotEmpty(txList)) {
            txDateList = txList.stream().map(SpcyRsJjrk::getFjjrsj).collect(Collectors.toList());
        }
        boolean tx = WorkDateUtils.isExists(startDate, txDateList); //判斷是否在调休内
        //如果是true 那就加一 否则不变
        if (tx){
            fsfyjjrlx = fsfyjjrlx + 1;
        }else {
            fsfyjjrlx = fsfyjjrlx;
        }
        user.setFsfyjjrlx(fsfyjjrlx);
        ycSysUserService.updateById(user);
        return Result.ok(user);

//        OaQxjsp byId = oaQxjspService.getById(oaid);
//        if (sflx(oaid, ts)) {
//            //相等返回true  当前日期，在调休列表中  则将用户表字段 本年度是否与节假日连休为 赋值为是
//
//            if (StringUtils.isBlank(fuserid)) {
//                return Result.error("查询不到本流程的申请用户id，请联系管理员");
//            }
//            YcSysUser user = ycSysUserService.getById(fuserid);
//            user.setFsfyjjrlx(OaFlowConstant.QXJ_YES);
//            ycSysUserService.updateById(user);
//        } else {
//            // 不相等返回false  当前日期，不在调休日期列表中
//            String fuserid = byId.getFuserid();
//            if (StringUtils.isBlank(fuserid)) {
//                return Result.error("查询不到本流程的申请用户id，请联系管理员");
//            }
//            YcSysUser user = ycSysUserService.getById(fuserid);
//            user.setFsfyjjrlx(OaFlowConstant.QXJ_NO);
//            ycSysUserService.updateById(user);
//
//        }

    }


    //在初始化提交流程的时候，个人的请休假类型为年休假且为流程在办的时候，则只能有一条数据
    public boolean onenxj(String fuserid) {
        List<OaQxjsp> list = oaQxjspService.list(new LambdaQueryWrapper<OaQxjsp>().eq(OaQxjsp::getFqjlx, OaFlowConstant.QXJ_NJ)
                .eq(OaQxjsp::getFuserid, fuserid)
                .eq(OaQxjsp::getFlczt, OaCommonFlowConstant.FLOW_LCZB));
        if (list.size() > 1) {
            return false; //如果大于1那就是不止有一条数据 ，其实还可以说 流程在办且为年假的请假记录只能有一条
        } else {
            return true;
        }
    }

    //年度信息 直接拿
    public Result getndxx() {
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        if (StringUtils.isBlank(currentUser.getId())) {
            return Result.error("当前登录已失效，请重新登录");
        }
        String id = currentUser.getId();

        //年度信息
        Map map = new HashMap(); // 结果集 map
        YcSysUser sysUser = ycSysUserService.getById(id);

        //int fnxjkxts = ycSysUser.getFnxjyxts();
        //int fnxjsyts = ycSysUser.getFnxjsyts();
        //int fnxjzjts = ycSysUser.getFnxjzjts();
        //        String ndxxmsg = "本年度可休年假：" + fnxjkxts + "天，" + "已休：" + fnxjyxts + "天，" + "剩余：" + fnxjsyts + "天";

        if(StringUtils.isBlank(sysUser.getFnxjyxts())){
            return Result.ok("当前用户没有年度信息，请联系管理员");
        }

        BigDecimal fnxjkxts = new BigDecimal(sysUser.getFnxjyxts());//应休天数

        BigDecimal fnxjsyts = new BigDecimal(sysUser.getFnxjsyts());//剩余天数
        BigDecimal fnxjyxts = fnxjkxts.subtract(fnxjsyts) ; //年休假已休天数 = 年休假可休天数 - 年休假剩余天数
        map.put( "fnxjkxts" , fnxjkxts); //可休
        map.put( "fnxjyxts" , fnxjyxts); //已休
        map.put( "fnxjsyts" , fnxjsyts); //剩余


        return Result.ok(map);
    }

    /**
     * @param: qxlx 请假类型，  ts 天数， njdbj 是否拿年假抵病假
     * @Description: 根据休假类型 获得请假信息
     * @auther: lhb
     * @date: 2023/9/15 9:12
     */
    public Result getqjxx(String qxlx,Integer ts,String njdbj) {
        CurrentUserVo currentUser = ThreadContextHelper.getCurrentUser();
        YcSysUser user = ycSysUserService.getById(currentUser.getId());
        BigDecimal fnxjsyts = new BigDecimal(user.getFnxjsyts());
        int i = fnxjsyts.compareTo(BigDecimal.valueOf(0));
        if (StringUtils.isNotBlank(qxlx)) {
            if (qxlx.equals(OaFlowConstant.QXJ_NJ)) {
                if (i == 0) {
                    return Result.ok("您本年度年假已休完，不能再申请年假,如有疑问请联系人事处！");
                }else {
                    return Result.ok("");
                }
            }
            if (qxlx.equals(OaFlowConstant.QXJ_SJ)) {
                return Result.ok("");
            }
            if (qxlx.equals(OaFlowConstant.QXJ_BJ)) {
                //病假可以拿年休假相抵
                if (njdbj.equals(OaFlowConstant.QXJ_YES)) {
                    if (i > 0) {
                        return Result.ok("优先扣除年假" + ts + "天，实情病假0天。");
                    } else {
                        return Result.ok("优先扣除年假0天，" + "实情病假" + ts + "天。");
                    }
                } else {
                    return Result.ok("请病假3天以上的需要提供医院出具的证明。");
                }
            }
        } else {
            return Result.error("没有获取到id,获取请假信息失败，请联系管理员");
        }
        switch (qxlx){
            case OaFlowConstant.QXJ_HJ:
                return Result.ok("婚假可休3个工作日。");
            case OaFlowConstant.QXJ_CJYH:
                return Result.ok("一孩产假可休158个自然日。");
            case  OaFlowConstant.QXJ_CJEH:
                return Result.ok("二孩产假可休168个自然日。");
            case OaFlowConstant.QXJ_CJSH:
                return Result.ok("三孩及以上产假可休178个自然日。");
            case OaFlowConstant.QXJ_CJJ:
                return Result.ok("");
            case OaFlowConstant.QXJ_CQJJPHJ:
                return Result.ok("产前检查陪护假可休5个自然日。");
            case OaFlowConstant.QXJ_HLJ:
                return Result.ok("护理假可休25个自然日。");
            case  OaFlowConstant.QXJ_YEJ:
                return Result.ok("育儿假可休10个自然日。");
            case OaFlowConstant.QXJ_SSJ:
                return Result.ok("丧假可休3个工作日。");
            case OaFlowConstant.QXJ_JZGX:
                return Result.ok("");
            default:
                return Result.error("没有匹配到你所需的请假类型，请联系管理员");
        }
    }


    /**
     * @param:
     * q'w@auther: lhb
     * @date: 2023/9/15 11:33
     * 3.清理转结：①剩余天数=  剩余天数＞应休？应休：剩余天数
     *           ②转结已休= 剩余天数＞应休？转结+应休-剩余：转结
     */
    public Result deletelZjnj(String userids) {

        List<String> userIdsList = Arrays.asList(userids.split(","));
        List<YcSysUser> ycSysUsers = ycSysUserService.listByIds(userIdsList);
        if (CollectionUtils.isNotEmpty(ycSysUsers)) {
            for (YcSysUser user : ycSysUsers) {
                if (user.getFsfyqlzj().equals(OaCommonFlowConstant.FSFYQLZJ_NO)){
                //使用bigdecimal 计算
                    BigDecimal fnxjsyts = new BigDecimal(user.getFnxjsyts());
                    BigDecimal fnxjyxts = new BigDecimal(user.getFnxjyxts());
                    BigDecimal fnxjzjts = new BigDecimal(user.getFnxjzjts());

                    int i = fnxjsyts.compareTo(fnxjyxts);
                    int i1 = fnxjsyts.compareTo(fnxjyxts);

                    BigDecimal newfnxjsyts = i > 0 ? fnxjyxts : fnxjsyts; //新的剩余天数
//                Integer newfzjyxts = i1 > 0 ? fnxjzjts+fnxjyxts-fnxjsyts : fnxjzjts; //新的转结已休天数

                    BigDecimal newfzjyxts = i1 > 0 ? fnxjzjts.add(fnxjyxts).subtract(fnxjsyts) : fnxjzjts; //新的转结已休天数


                    user.setFsfyqlzj(OaCommonFlowConstant.FSFYQLZJ_YES);
                user.setFnxjsyts(String.valueOf(newfnxjsyts));
                user.setFzjyxts(String.valueOf(newfzjyxts));
                ycSysUserService.updateById(user);
                }

            }
        } else {
            return Result.error("清空转结错误，无法获取用户，请联系管理员");
        }
        return Result.ok("清空转结成功");
    }


    /**
     * @param:
     * @Description: 转结上一年年休假天数 ,转结上一年休假天数的时候，把当前的数据复制到年休假历史表 并且更新当前工龄 和 当前年的可休年假数
     *                  手动转结
     * @auther: lhb
     * @date: 2023/9/15 11:57
     *
     * 1.初始化：①年假剩余天数= 应休+转结   ②应休=按工龄计算  从配置得来
     * 2.请假扣减：减掉剩余天数
     * 3.清理转结：①剩余天数=  剩余天数＞应休？应休：剩余天数  ②转结已休= 剩余天数＞应休？转结+应休-剩余：转结
     */
    public Result zjNxj(String userids) {
        //先判断一次在手动转结当天是否有未办完的年休假请假数据
        List<OaQxjsp> list = oaQxjspService.list(new LambdaQueryWrapper<OaQxjsp>().eq(OaQxjsp::getFqjlx, OaFlowConstant.QXJ_NJ)
                .eq(OaQxjsp::getFlczt, OaCommonFlowConstant.FLOW_LCZB));
        if (list.size() > 1) {
           throw new BusinessException("有未办完的年休假请假流程，请办结完成后在手动转结");
        }
        BigDecimal ys = new BigDecimal(12); //一年的月数

        //先把现在的数据复制到历史表

        List<String> userIdsList = Arrays.asList(userids.split(","));
        List<YcSysUser> ycSysUsers = ycSysUserService.listByIds(userIdsList);

        List<OaNxjhistory> nxjhistories = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(ycSysUsers)) {
            for (YcSysUser userid : ycSysUsers) {
                if (userid.getFsfyqlzj().equals(OaCommonFlowConstant.FSFYQLZJ_NO)){
                    OaNxjhistory oaNxjhistory = new OaNxjhistory();
                    oaNxjhistory.setId(GetUuIdUtils.ReplaceUuId());
                    oaNxjhistory.setFuserName(userid.getRealname());
                    oaNxjhistory.setFuserId(userid.getId());
                    oaNxjhistory.setFzw(userid.getFzw());
                    oaNxjhistory.setFbm(userid.getOrgName());
                    oaNxjhistory.setFgzdw(userid.getFgzdw());
                    oaNxjhistory.setFxb(userid.getSex());
                    oaNxjhistory.setFcjgzsj(DateConversionUtils.DateToString(userid.getFcjgzsj())); //未导入数据之前 暂时不放开
                    oaNxjhistory.setFnxjsyts(userid.getFnxjsyts());
                    oaNxjhistory.setFnxjkxts(userid.getFnxjyxts());
                    oaNxjhistory.setFnxjzjts(userid.getFnxjzjts());
                    oaNxjhistory.setFgl(userid.getFgl());
                    oaNxjhistory.setFnxjyxqjssj(DateConversionUtils.DateToString(new Date()));
                    oaNxjhistory.setFnd(DateConversionUtils.DateToYear(new Date()));
                    oaNxjhistory.setFnd(userid.getFdqnjnd());
                    nxjhistories.add(oaNxjhistory);
                }
            }
            oaNxjhistoryService.saveBatch(nxjhistories);

//            //将用户本表的剩余年休假赋值为转结年休假，更新工龄数，并根据更新后的工龄数  重新赋值年休假可休天数和剩余天数 ，将已休天数归零
//            for (YcSysUser updatenxj : ycSysUsers) {
//                int oldsyts = updatenxj.getFnxjsyts(); //更新前的上一年年休假剩余天数 （包含转结天数）
//
//
//                //更新工龄数 几点几年 用来赋值可休年数
//                //工作时间 =当前工作时间- 参加工作时间 -间隔年/月
//                SimpleDateFormat nowdate = new SimpleDateFormat("yyyy-MM");
//                SimpleDateFormat cjgzdate = new SimpleDateFormat("yyyy-MM");
//                Date date = new Date();
//                Date fcjgzsj = updatenxj.getFcjgzsj();
//
//
//                int fjkns = updatenxj.getFjkns();
//
//                List list1 = spcyRsJjrkService.DayCompare(fcjgzsj, date);
//                double year = (int) list1.get(0);
//                double month = (int) list1.get(1);
//
//                //真实工龄数(月) = 当前年月 - 参见工作年月-间隔年月
//                double dqgls = (year * 12 + month) - fjkns;
//
//                //返回2位小数，并且四舍五入
//                DecimalFormat df = new DecimalFormat("######0.0");
//                //真实工龄数
//                String zsgls = df.format(dqgls / 12);
//
//                updatenxj.setFgl(zsgls); //赋值当前转结的时候的工龄数
//                //转为int类型然后比较
//                double gl = Double.parseDouble(zsgls);
//                //根据工龄数查询当前请休假配置并且赋值 新的可休天数
//                List<OaQxjpz> cxjg = oaQxjpzService.list(new LambdaQueryWrapper<OaQxjpz>().le(OaQxjpz::getFzxgls, gl)
//                        .ge(OaQxjpz::getFzdgls, gl));
//                int ts = 0;
//                for (OaQxjpz gljg : cxjg) {
//                    ts = gljg.getFnxjts(); //拿到转结后本年度应休的天数
//                }
//                //更新转结天数 和可休天数 和剩余天数
//                updatenxj.setFnxjzjts(oldsyts);
//                updatenxj.setFnxjkxts(ts + oldsyts);
//                updatenxj.setFnxjsyts(ts + oldsyts);
//            }
//            ycSysUserService.saveOrUpdateBatch(ycSysUsers);
//        } else {
//            return Result.error("获取不到用户数据，请联系管理员");
//        }
//        return Result.ok("更新成功");

            /**
             * 1.初始化：①年假剩余天数= 应休+转结   ②应休=按工龄计算  从配置得来
             * 2.请假扣减：减掉剩余天数
             * 3.清理转结：①剩余天数=  剩余天数＞应休？应休：剩余天数  ②转结已休= 剩余天数＞应休？转结+应休-剩余：转结
             */

            //年假剩余天数= 应休+转结
            for (YcSysUser updatenxj:ycSysUsers){
                String fnxjsyts = updatenxj.getFnxjsyts(); //上一年的剩余天数

                //根据工龄来计算当前年应休天数
                //当前年数 - 参见工作时间 - 间隔月数 = 真实工作时间
                LocalDate currentDate = LocalDate.now(); // 获取当前日期
                Date fcjgzsj = updatenxj.getFcjgzsj(); //参见工作时间


                LocalDate cjgzsj = fcjgzsj.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();



                int jgys = updatenxj.getFjkns(); // 间隔月数
                Period realWorkingPeriod = Period.between(cjgzsj,currentDate); // 计算真实的工作时间间隔
                int realWorkingYears = realWorkingPeriod.getYears(); // 获取工作年数

                //工作年数-间隔月数  = 真实工作时间
                BigDecimal jgysBigDecimal = new BigDecimal(jgys);
                BigDecimal jgns = jgysBigDecimal.divide(ys, 2, RoundingMode.HALF_UP);
                BigDecimal yearBigDecimal = new BigDecimal(realWorkingYears);
                BigDecimal zsgzsj = yearBigDecimal.subtract(jgns);//真实工作时间
                updatenxj.setFgl(String.valueOf(zsgzsj));

                int zssj = zsgzsj.intValue();


//                String fnxjts = "0";
                BigDecimal fnxjts = new BigDecimal(0);
                if (zssj > OaCommonFlowConstant.NXJ_ZDGLS){
                    fnxjts = new BigDecimal(OaCommonFlowConstant.NXJ_ZDTS) ;
                }else {
                    fnxjts =new BigDecimal(OaCommonFlowConstant.NXJ_TS);
                }

                BigDecimal sytsbigDecimal = new BigDecimal(fnxjsyts);
                //更新 剩余天数 应休天数 和 转结天数
                updatenxj.setFnxjyxts(String.valueOf(fnxjts)); //应休天数
                updatenxj.setFnxjzjts(fnxjsyts); //转结天数
                updatenxj.setFnxjsyts(String.valueOf(fnxjts.add(sytsbigDecimal))); //剩余天数 = 应休天数 + 转结天数
                //更新当前年假年度

                updatenxj.setFdqnjnd(String.valueOf(LocalDate.now().getYear()));
                //更新转结已休天数
                updatenxj.setFzjyxts(OaCommonFlowConstant.FZJYXTS);
                //更新是否已清理转结
                updatenxj.setFsfyqlzj(OaCommonFlowConstant.FSFYQLZJ_NO);
                ycSysUserService.updateById(updatenxj);

            }

        }else {
            throw new BusinessException("获取不到用户数据，请联系管理员");
        }
        return Result.ok("更新成功");
    }


}
